Repository navigation
Add 蹬王之王 (expiry-guardian) · 只读版:本地到期账本与用卡决策(不碰宿主任何私有数据) - #47
Hylouis233 wants to merge 3 commits into
Conversation
这是「只读版」,与 #39 是二选一
两者的决策逻辑一字未改(三方 Rust / Mini App / Python 仍 19/19 逐字一致), ⇒ 管理员 review 的原话是「很欢迎你提的方案:把只读、能直接交付的部分……单独开一个 PR。 请先决定走哪条路;如果走只读版,#39 可以直接关掉。 |
社区插件版本的蹬王之王:**看你自己维护的本地账本,算出「该用卡还是该留积分」**。 ## 为什么不碰宿主的三类私有数据 上游社区插件有三条硬红线(2026-10-20 管理员 review 明确列出): | 红线 | v1.x(已移除) | v2.0 | | --- | --- | --- | | 不能读 MiniMax Code 的登录凭据 | 读 lease socket / .cap 取 token 调账号接口 | 不读。数据源是本地账本 | | 不能读写宿主内部数据库 | UPDATE/DELETE/INSERT 目标与队列、读回合记录 | 不碰。只读插件自己的目录 | | 不能读别的插件的数据目录 | 读 minimax-bot 的 state.json 拿 bot 与会话 id 去发消息 | 不读。Bot 看门狗整体移除 | ⇒ **不扣卡、不暂停目标、不叫醒 bot**:只把结论算准、说清楚,动作由人做。 ## 亮点 - **决策逻辑一字未改**:Rust / Mini App / Python 三方同构, verify-parity.mjs 仍 **19/19 三方逐字一致**(动作 + 理由文本)。 变的只是「数据从哪来」。 - **本地账本**:~/.config/mcode-reset-card/ledger.json,面板底部可直接编辑并保存。 - **诚实失败**:账本读不到 ⇒ 明确报「本轮没有任何结论」; **读不到 ≠ 没有** ⇒ 数据不完整时永远不给「用卡」这种花钱的建议。 - **红线守卫**(19 项):把上面三条红线变成**可执行的门禁** —— 谁把旧代码加回来,CI 立刻红。v1.x 那些代码在仓库里躺了好几个版本才被发现。 ## 校验 上游 npm run validate 对本插件 **OK**(0 错 0 警)、repository: OK、npm test 69/69。 本插件:Rust 25/25、Python 20/20、MiniApp 79/79、三方一致性 19/19。 ## 文档 - plugins/hylouis233/expiry-guardian/README.md —— 英文 - plugins/hylouis233/expiry-guardian/docs/README.zh-CN.md —— 中文 - plugins/hylouis233/expiry-guardian/docs/BOT_DIAGNOSIS.md —— 排查手册
v2.0 已经不调任何账号接口、不再取 lease token,但文件头还在描述旧的 两套 API 与鉴权方式 ⇒ 会被误读成「这个插件还在调接口」。 改成如实描述本地账本这一唯一数据源,并写明为什么不再自己调接口。
383a063 to
9a9cb7f
Compare
MyPrototypeWhat
left a comment
There was a problem hiding this comment.
COMMENT(head 9a9cb7f)
感谢单独开出这个只读版。v2.0 已经去掉了读取凭据、访问宿主数据库和读取其他插件数据这几部分,符合社区插件的红线。
不过裁掉这些之后,数据只能由用户手动填写,插件目前的实际用处比较有限。这部分先暂停,等有合规的取数方式再继续。是否关闭由你决定。
如果继续保留这个 PR,请顺手处理这几处:
.minimax-plugin/plugin.json的 description 还在写已经移除的功能(自动暂停目标、自动用卡、Bot 守护),版本号也还是 1.6.0,请改成和现在的行为一致。server.mjs里请删除已移除功能的残留注释。daemon/rust/src/decision.rs:342:含*const u8字段的结构体上#[derive(Default)]会报 E0277,cargo build --release编译不过。Cargo.toml里的ureq依赖已经没用了,可以删掉。- 面板文案里还在写「暂停目标 / 动用重置卡」一类说法,请改成和只读提醒一致的表述。
| "name": "expiry-guardian", | ||
| "displayName": "蹬王之王", | ||
| "version": "1.6.0", | ||
| "description": "实时追踪积分与重置卡的到期时间,额度打满时自动暂停所有进行中的目标、额度回落后自动恢复并叫醒;无人值守后台守护进程配合 Mini App 看板,按「先过期先用」自动使用重置卡,遇到 500/429 等可重试错误会一直重试。v1.6 修掉一个让 Bot 守护完全静默的真 bug(minimax-bot 状态文件里一个被截断的代理对转义导致严格 JSON 解析失败),并新增唤醒链路自检:宿主重启后运行时没起来时如实告警、投递空转时也能发现,绝不再「看起来一切正常、实际一个 bot 都没叫醒」。", |
There was a problem hiding this comment.
这段描述还在写已经移除的功能(自动暂停/恢复目标、叫醒、自动用卡、Bot 守护),版本也还是 1.6.0。请改成现在的实际行为:基于本地账本的到期提醒和用卡建议,只读,不自动扣卡;版本号请一并更新。
There was a problem hiding this comment.
已改。描述改成只读版的实际行为(基于本地账本的到期提醒与用卡建议、只读、不自动扣卡),版本号 1.6.0 → 2.0.0。
| schemaVersion: 1, | ||
| cardTriggerPercent, | ||
| cardSkipBeforeResetMinutes, | ||
| // ⚠️ `resumeCronId` 已彻底删除(2026-10-20):本插件不再武装/解除武装任何 cron。 |
There was a problem hiding this comment.
请删除已移除功能的残留注释(此处 resumeCronId / Bot 投递相关,以及文件中其他已移除能力的注释块)。
There was a problem hiding this comment.
已删。server.mjs 里所有已移除能力的残留注释块都清掉了(resumeCronId / Bot 投递相关,以及整段「Bot 唤醒循环」注释)。
| context.signal.addEventListener('abort', onAbort, { once: true }); | ||
| if (context.signal.aborted) await dispose(); | ||
|
|
||
| // ── Bot 唤醒循环 ── |
There was a problem hiding this comment.
请删除已移除功能的残留注释(「Bot 唤醒循环」整段)。
There was a problem hiding this comment.
已删 —— 整段「── Bot 唤醒循环 ──」注释块(那段描述的是早已移除的功能)。
| /// 桌面端与 Python 版都用本地时区展示;这里手算避免引入 chrono 依赖。 | ||
| /// libc 的 `struct tm`,只需本地时区换算用到的字段。 | ||
| #[repr(C)] | ||
| #[derive(Default)] |
There was a problem hiding this comment.
*const u8 没有实现 Default,这里会导致 cargo build/test --release 报 E0277,编译失败。可以去掉 derive,改用 unsafe { std::mem::zeroed() } 来初始化。
There was a problem hiding this comment.
已改。#[derive(Default)] 去掉,改成手写 impl(全零 tm + tm_zone: std::ptr::null())—— 语义与 derive 一致,但不再依赖 impl Default for *const T 在各版本工具链里是否可用。
感谢指出:我本地 rustc 1.98 能编过,所以没发现;老工具链会直接 E0277 ⇒ 整个包装不上。手写实现是唯一稳妥的解法。
|
|
||
| [dependencies] | ||
| # HTTP 客户端:手写 TLS 容易出错且难维护,用成熟实现更可靠 | ||
| ureq = { version = "3", default-features = false, features = ["rustls", "json", "gzip"] } |
There was a problem hiding this comment.
可选:守护进程已经不再联网,ureq 可以删掉。
There was a problem hiding this comment.
已删。守护进程不再联网,ureq 连同 Cargo.lock 里的记录都清掉了。
1. **plugin.json 的描述与版本号还停在 1.6.0 的老功能** —— 改成只读版的实际功能, 版本 → 2.0.0。 2. **server.mjs 里有残留的旧注释** —— 删掉整段「── Bot 唤醒循环 ──」 (功能早已移除,注释还在描述它),并把「已暂停自动扣卡」改成「不建议用卡」。 3. **decision.rs:342 的 `#[derive(Default)]` 会让 cargo 编译报 E0277** —— `*const u8` 的 `Default` 实现并非所有 Rust 工具链都有。 ⇒ 改成**手写 impl**(全零 tm,语义与 derive 一致,不依赖工具链版本)。 4. **Cargo.toml 里有用不上的 `ureq` 依赖** —— 本插件不再调任何 HTTP 接口 ⇒ 去掉 (Cargo.lock 同步)。 5. **面板上「暂停目标 / 动用重置卡」这类说法要改** —— 「自动执行」统一改成 「自动刷新」,并把所有「不会真的扣卡」补成「本插件只读」的口径。 校验:上游 `npm run validate` → 本插件 **OK**(0 错 0 警)、`repository: OK`; Rust 25/25、Python 20/20、MiniApp 79/79、三方一致性 19/19。
五处都改了
校验:上游 关于「只靠手填数据用处有限」这点我同意 —— 目前账本确实要手填,插件的决策逻辑再准,喂进去的数据不对也没用。 所以想请你定个方向:
你说先放着,那我就先开着,不动它;你哪天觉得没意义,说一句我就关掉。 |
MyPrototypeWhat
left a comment
There was a problem hiding this comment.
感谢跟进!上次提到的几处都看过了,改得很到位 🙏
plugin.json:description 已经和只读行为一致,版本号也改成了 2.0.0。✅server.mjs:已移除功能的大段残留注释清掉了。✅decision.rs:改成手写impl Default for Tm,cargo check/cargo test本地都通过(25 个测试全过)。✅Cargo.toml:ureq去掉了,Cargo.lock也跟着瘦身了。✅- 面板文案:改成「自动刷新 / 只给建议 / 不会真的扣卡」,读起来很清楚。✅
npm run check 在这个 head 上也通过了(expiry-guardian: OK)。
另外还有几处很小的尾巴,完全不影响结论,有空的话顺手清一下就好:
miniapp/client/index.html约 485、809 行,miniapp/node/server.mjs约 1133 行,还有一些「目标自动暂停」相关的旧注释。index.html里CARD_ERROR/CARD_FAILED的判断(约 1285、1318 行)在 v2.0 里应该不会再出现了,可以考虑去掉。daemon/reset_card_autouse.py和daemon/verify-parity.mjs里还留着goalPause的默认配置。
这个 PR 可以先留着,取数这块我们先缓一缓,等有合规的取数方式再继续推进;要不要关掉你来定就好。再次感谢你的耐心跟进!
这是什么
社区插件版本的蹬王之王(Expiry Guardian):看你自己维护的本地账本,
算出「该用卡还是该留积分」,并把理由说清楚。
Mini App 看板 + Rust 后台守护进程(
launchd常驻,只读)。为什么不碰宿主的三类私有数据
上游社区插件有三条硬红线(2026-10-20 管理员 review 明确列出)。这一版按红线裁剪:
.cap取 access token,再拿它调账号接口sqlite3直接UPDATE/DELETE/INSERT目标与执行队列,还读回合记录minimax-bot的state.json拿 bot 与会话 id,再往那些会话发消息⇒ 代价是明确的:v2.0 不再自动扣卡、不再自动暂停目标、不再自动叫醒 bot。
它只负责把结论算准、说清楚,动作由你自己做。
⇒ 好处也很明确:这是一份能进社区仓库的代码 ——
不碰宿主任何私有数据,行为全部可预测。
本地账本
路径:
~/.config/mcode-reset-card/ledger.json(面板底部可直接编辑并保存){ "schemaVersion": 1, "updatedAtMs": 1792480000000, "quota": { "fiveHour": { "usedPercent": 3, "totalPercent": 100, "unlimited": false, "resetTimeMs": 1792497600000 }, "weekly": { "usedPercent": 0, "totalPercent": 100, "unlimited": true, "resetTimeMs": 1792944000000 } }, "cards": [ { "cardId": "card_1", "label": "Card A", "sourceType": "code", "outBizNo": "biz_1", "expireTimeMs": 1795000000000 } ], "credits": [ { "label": "Granted", "source": "code", "granted": 400, "used": 0, "balance": 400, "expireTimeMs": 1795017600000 } ] }outBizNo与sourceType两个都要有;已过期的也不算balance > 0且未过期credits字段 ≠ 没有积分 ⇒ 判成「数据不完整」⇒ 结论停在「暂不处理」,绝不会因为「读不到」就反过来建议你烧掉一张真卡
决策逻辑:先过期先用
三方一致性(决策逻辑一字未改)
Rust / Mini App / Python 三份同构实现,
daemon/verify-parity.mjs让三方读同一份用例,逐字比对「动作 + 理由文本」:
裁剪只改了「数据从哪来」,决策引擎的输入结构与之前从账号接口拿到时完全一致。
红线守卫(19 项)
tests/server-lint.test.mjs把上面三条红线变成可执行的门禁:.cap/ token 落盘runtime-state.sqlite/ 宿主表的UPDATE·DELETE·INSERTplugin-data/liveboards/ 别的插件的state.json⇒ 谁不小心把旧代码加回来,CI 立刻红。
(v1.x 那些代码在仓库里躺了好几个版本才被发现 —— 人工审计靠不住。)
后台守护进程(只读)
daemon-status.jsonlocal MCP 端点
watchdog_statuswatchdog_decide校验
npm run validaterepository: OKnpm test文档
plugins/hylouis233/expiry-guardian/README.md—— 英文plugins/hylouis233/expiry-guardian/docs/README.zh-CN.md—— 中文plugins/hylouis233/expiry-guardian/docs/BOT_DIAGNOSIS.md—— 排查手册Need help on this PR? Tag
@codesmith-botwith what you need.